home *** CD-ROM | disk | FTP | other *** search
-
- /*
- * colorfun.c
- * X Window demo program that draws a colored box
- * in a window. Every second, we change the color.
- *
- * To compile and run this program, you
- * will need to link in the X library
- * (usually called Xlib), usually done with
- * a command something like:
- *
- * cc -o colorfun colorfun.c -lX11
- *
- * (On UNIX systems.)
- *
- * Note that we use some functions found only
- * in the Release 4 Xlib. These functions are
- * marked as such, so if you have an R3 or
- * older system you can easily convert.
- *
- * Written for Computer Language magazine
- * by E F Johnson and K Reichard, 1990.
- *
- */
-
- #include <stdio.h>
-
- /*
- * Most X programs will need Xlib.h and Xutil.h
- */
- #include <X11/Xlib.h>
- #include <X11/Xutil.h>
-
-
-
- main( argc, argv )
-
- int argc;
- char *argv[];
-
- { /* -- main */
- Display *display;
- int screen;
- Window window;
- GC gc;
- int done;
- XColor the_color;
- Visual *visual;
- int depth;
- XFontStruct *font;
- int status;
- Colormap colormap;
- unsigned long black, white;
-
-
- /*
- * 1) Set up X display connection with the server
- * named in the user's DISPLAY environment variable.
- */
- display = XOpenDisplay( NULL );
-
- if ( display == (Display *) NULL )
- {
- (void) fprintf( stderr, "Error: Could not open display\n" );
- exit( 1 );
- }
-
-
- /*
- * 2) Find a visual that supports color and get its depth.
- */
- screen = DefaultScreen( display );
-
- SetUpVisual( display, screen, &visual, &depth );
-
-
- /*
- * 3a) Create Color map and get a black and white
- * pixel values for the colormap.
- */
- SetUpColormap( display, screen, visual, &colormap, &black, &white );
-
-
- /*
- * 3b) Allocate one read-write color cell.
- */
- status = XAllocColorCells( display, colormap,
- False, NULL, 0, &the_color.pixel, 1 );
-
- if ( status == 0 )
- {
- (void) fprintf( stderr, "Error in allocating color cell.\n" );
- XCloseDisplay( display );
- exit( 1 );
- }
-
- /*
- * Set up some "random" RGB color values.
- */
- the_color.red = ( 1 << 8 );
- the_color.green = ( 104 << 8 );
- the_color.blue = ( 200 << 8 );
-
- /*
- * 4) Load a font
- */
- font = XLoadQueryFont( display, "fixed" );
-
- if ( font == (XFontStruct *) NULL )
- {
- (void) fprintf( stderr, "Error loading fixed font\n" );
- XCloseDisplay( display );
- exit( 1 );
- }
-
-
- /*
- * 5) Create a window and set ICCCM values.
- */
- SetUpWindow( display, visual, depth, colormap, black, white, &window );
-
-
- /*
- * 6) Create a graphics context (GC) for our window.
- */
- gc = XCreateGC( display, window, 0x0, (XGCValues *) NULL );
- XSetFont( display, gc, font->fid );
- XSetBackground( display, gc, white );
-
-
- /*
- * 7) "Map" our window, making it appear
- * on the screen.
- */
- XMapRaised( display, window );
- XFlush( display );
-
-
- /*
- * 8) Loop on events, exit on a ButtonPress event.
- */
- done = False;
- while( !done )
- {
- done = CheckForEvents( display, window, gc,
- &the_color, black );
-
- /*
- * 9) Sleep for a second,
- * to space out the color changes.
- */
- sleep( 1 );
-
-
- /*
- * 10) Change the color in our window.
- */
- ChangeColor( display, colormap, &the_color );
-
-
- /*
- * 11) Redraw with the new color
- */
- Redraw( display, window, gc, &the_color, black );
- }
-
- /*
- * 12) Free/Destroy our window, GC, and font.
- */
- XDestroyWindow( display, window );
- XFreeGC( display, gc );
- XFreeFont( display, font );
-
-
- /*
- * 13) Close our X display connection and quit.
- */
- XCloseDisplay( display );
- exit( 0 );
-
- } /* -- main */
-
-
- CheckForEvents( display, window, gc, the_color, black )
-
- Display *display;
- Window window;
- GC gc;
- XColor *the_color;
- unsigned long black;
-
-
- /*
- * 8) Loop on events.
- * CheckForEvents() checks to see if an X event
- * is pending. If so, CheckForEvents() reads in
- * that event and then acts on it (perhaps by
- * doing nothing). We ignore changes to the window's
- * size (it is assumed the user will be too
- * dazzled by the program to even think about resizing
- * the window).
- */
-
- { /* -- function CheckForEvents */
- XEvent event;
- int done = False;
-
- /*
- * 8a) Do we have an event waiting?
- */
- if ( XPending( display ) > 0 )
- {
- XNextEvent( display, &event );
-
- switch( event.type )
- {
- /*
- * 8b) Set a flag if a mouse button
- * is pressed. We will exit later.
- */
- case ButtonPress:
- done = True;
- break;
-
- /*
- * 8c) Only redraw our window when
- * the last Expose event comes in.
- */
- case Expose:
- if ( event.xexpose.count == 0 )
- {
- Redraw( display, window,
- gc, the_color, black );
- }
- break;
- }
- }
-
- return( done );
-
- } /* -- function CheckForEvents */
-
-
-
- Redraw( display, window, gc, the_color, black )
-
- Display *display;
- Window window;
- GC gc;
- XColor *the_color;
- unsigned long black;
-
-
- /*
- * Redraw() redraws our window. Redraw()
- * is called whenever the window's contents
- * need to be refreshed, because the contents
- * have changed, or because the window system
- * requests we redraw the window due to "damage".
- */
-
- { /* -- function Redraw */
- char string[ 120 ];
-
- /*
- * Fill in a rectangle, in the given color.
- */
- XSetForeground( display, gc, the_color->pixel );
-
- XFillRectangle( display, window, gc,
- 10, 30, 200, 100 );
-
-
- /*
- * Draw text in black
- */
- XSetForeground( display, gc, black );
-
-
- /*
- * Display current color values as text
- */
- (void) sprintf( string, "R 0x%5.5x G 0x%5.5x B 0x%5.5x",
- the_color->red,
- the_color->green,
- the_color->blue );
-
-
- XDrawImageString( display, window, gc,
- 10, 20,
- string, strlen( string ) );
-
- /*
- * Send output requests to the X server
- */
- XFlush( display );
-
- } /* -- function Redraw */
-
-
-
- SetUpColormap( display, screen, visual, colormap, black, white )
-
- Display *display;
- int screen;
- Visual *visual;
- Colormap *colormap;
- unsigned long *black, *white;
-
- /*
- * SetUpColormap() creats an X colormap using the
- * given screen and visual. Color cells (pixels)
- * for "black" and "white" are also allocated in
- * our new colormap.
- */
-
- { /* -- function SetUpColormap */
- int status;
- XColor hardwarecolor, exactcolor;
-
-
- /*
- * Create a colormap using the
- * visual found in SetUpVisual().
- */
- *colormap = XCreateColormap( display,
- RootWindow( display, screen ),
- visual,
- AllocNone );
-
-
- /*
- * Check for failure.
- */
- if ( *colormap != None )
- {
- /* -- Set up "white" in the new colormap */
- status = XAllocNamedColor( display, *colormap, "white",
- &hardwarecolor,
- &exactcolor );
-
- if ( status != 0 )
- {
- *white = hardwarecolor.pixel;
-
-
- /* -- Set up "black" in the new colormap */
- status = XAllocNamedColor( display, *colormap, "black",
- &hardwarecolor,
- &exactcolor );
-
- *black = hardwarecolor.pixel;
- }
- }
- else
- {
- status = 0;
- }
-
- if ( status == 0 )
- {
- (void) fprintf( stderr, "Error in creating colormap\n" );
- XCloseDisplay( display );
- exit( 1 );
- }
-
- } /* -- function SetUpColormap */
-
-
-
- SetUpVisual( display, screen, visual, depth )
-
- Display *display;
- int screen;
- Visual **visual;
- int *depth;
-
- /*
- * SetUpVisual() finds a PseudoColor visual
- * on the given screen. If none is to be found,
- * the program will terminate. *depth is set to
- * the depth of the found visual.
- */
-
- { /* -- function SetUpVisual */
- int number_visuals;
- XVisualInfo *visual_array, visual_template;
-
- /*
- * We want a PseudoColor visual on this screen.
- * XGetVisualInfo() will get a list of all
- * the PseudoColor visuals supported on
- * this screen.
- */
- visual_template.class = PseudoColor;
- visual_template.screen = screen;
-
- visual_array = XGetVisualInfo( display,
- VisualClassMask | VisualScreenMask,
- &visual_template,
- &number_visuals );
-
- /* -- Check for success */
- if ( ( number_visuals > 0 ) && ( visual_array != NULL ) )
- {
- /*
- * We're lazy, we just choose the
- * first PseudoColor visual
- */
- *visual = visual_array[0].visual;
- *depth = visual_array[0].depth;
-
- XFree( visual_array );
- }
- else
- {
- (void) fprintf( stderr, "Error in finding visual\n" );
- XCloseDisplay( display );
- exit( 1 );
- }
-
- } /* -- function SetUpVisual */
-
-
-
- SetUpWindow( display, visual, depth, colormap, fore, back, window )
-
- Display *display;
- Visual *visual;
- int depth;
- Colormap colormap;
- unsigned long fore, back;
- Window *window;
-
- /*
- * 5) Create a window. We need to be careful here
- * to use our visual and colormap.
- */
-
- { /* -- function SetUpWindow */
- int x, y, width, height;
- XSetWindowAttributes attributes;
- unsigned long attribute_mask;
- int screen;
- XWMHints *wmhints;
- XSizeHints *sizehints;
-
-
-
- /*
- * 5a) Determine x, y, width, height. Normally
- * in X, the user should be able to specify this
- * on the UNIX command-line. For simplicity,
- * we're just using arbitrary values here.
- */
- x = 10;
- y = 10;
- width = 220;
- height = 140;
-
-
- /*
- * 5b) Fill in a window attributes structure.
- * fore and back arer the black and white colors
- * allocated in our new colormap. If we use
- * the default BlackPixel() and WhitePixel(),
- * we may get strange values since these
- * may not have been allocated in our new
- * colormap.
- */
- attributes.background_pixel = back;
- attributes.border_pixel = fore;
- attributes.event_mask = ExposureMask | ButtonPressMask;
- attributes.colormap = colormap;
-
-
- attribute_mask = CWBackPixel | CWBorderPixel |
- CWEventMask | CWColormap;
-
-
-
- /*
- * 5c) Create window
- */
- screen = DefaultScreen( display );
-
- *window = XCreateWindow( display,
- RootWindow( display, screen ), /* parent window */
- x, y, width, height,
- 2, /* -- border width */
- depth,
- InputOutput, /* -- window class */
- visual, /* -- our visual */
- attribute_mask,
- &attributes );
-
-
- if ( *window == (Window) None )
- {
- (void) fprintf( stderr, "Error: could not open window\n" );
- XCloseDisplay( display );
- exit( 1 );
- }
-
-
- /*
- * 5d) Store a name for the window
- * with the window manager. Note we are
- * using Latin-1 names, so users in Japan
- * or Arabia might want to use X's compound
- * text mechanism.
- */
- XStoreName( display, *window, "ColorFun" );
-
-
- /*
- * 5e) Set window manager hints, R4-only functions!
- */
- wmhints = XAllocWMHints();
-
- if ( wmhints != NULL )
- {
- wmhints->initial_state = NormalState;
- wmhints->input = True;
- wmhints->flags = StateHint | InputHint;
-
- XSetWMHints( display, *window, wmhints );
-
- XFree( wmhints );
- }
-
-
- /*
- * 5f) Set Size hints, again R4-specific!
- * (This also requires an R4 or ICCCM-compliant
- * window manager.)
- */
- sizehints = XAllocSizeHints();
-
- if ( sizehints != NULL )
- {
- sizehints->base_width = width;
- sizehints->base_height = height;
-
- sizehints->flags = PBaseSize;
-
- XSetWMNormalHints( display, *window, sizehints );
-
- XFree( sizehints );
- }
-
-
- } /* -- function SetUpWindow */
-
-
-
- ChangeColor( display, colormap, color )
-
- Display *display;
- Colormap colormap;
- XColor *color;
-
- /*
- * Every second, ChangeColor() is called to
- * modify the current color we are displaying.
- */
-
- { /* -- function ChangeColor */
-
-
- color->flags = DoRed | DoGreen | DoBlue;
-
- color->red = (unsigned short) IncrementValue( color->red, 3 );
- color->green = (unsigned short) IncrementValue( color->green, 6 );
- color->blue = (unsigned short) IncrementValue( color->blue, 5 );
-
- XStoreColor( display, colormap, color );
-
- } /* -- function ChangeColor */
-
-
-
- IncrementValue( value, amount )
-
- short value;
- int amount; /* -- add this amount to value. */
-
- /*
- * Some common 8-plane color systems seem to just
- * use the upper byte of the color values for
- * Red, Green and Blue (hence all the >> and <<
- * bit-shift operations). If you don't like how
- * these colors look on your system, change
- * IncrementValue() and ChangeColor() to do what
- * you'd like. Play around with them and have fun.
- */
-
- { /* -- function IncrementValue */
- unsigned short new_value;
-
- new_value = ( value >> 8 );
-
- new_value += amount;
-
- /*
- * Spend more time with brighter colors.
- */
- if ( new_value > 200 )
- {
- new_value--;
- }
-
- if ( new_value > 250 )
- {
- new_value = 0;
- }
-
- return( new_value << 8 );
-
- } /* -- function IncrementValue */
-
- /*
- * end of file
- */
-